/**

   dc.c
   ====

   Datacenter management

**/


/**

   Includes
   --------

   - stdlib.h   : malloc, free
   - stdint.h   : uintX_t
   - chunksrv.h : chunkservers
   - heap.h     : heaps
   - dc.h       : self header

**/


#include <stdlib.h>
#include <stdint.h>
#include "chunksrv.h"
#include "heap.h"
#include "dc.h"




/**

   Function: struct dc* dc_create(uint64_t id, unsigned int max)
   -------------------------------------------------------------

   Create a datacenter, containing `max` chunk servers

**/


struct dc* dc_create(uint64_t id, unsigned int max)
{
  struct dc* dc;

  /* Sanity check */
  if (!max)
    {
      return NULL;
    }

  /* Allocate DC */
  dc = (struct dc*)malloc(sizeof(struct dc));
  if (dc == NULL)
    {
      return NULL;
    }

  /* Create heap */
  dc->heap = heap_create(max,chunksrv_compare);
  if (dc->heap == NULL)
    {
      free(dc);
      return NULL;
    }

  /* Fields */
  dc->id = id;
  dc->next = NULL;
  dc->prev = NULL;

  return dc;

}


/**

   Function: int dc_delete(struct dc* dc)
   --------------------------------------

   Delete `dc`

**/

int dc_delete(struct dc* dc)
{
  /* Delete heap */
  heap_delete(dc->heap);

  /* Delete dc */
  free(dc);

  return EXIT_SUCCESS;
}


/**

   Function: int dc_insert(struct dc* dc, struct chunksrv* cs)
   -----------------------------------------------------------

   Insert `cs` into `dc`

**/


int dc_insert(struct dc* dc, struct chunksrv* cs)
{
  cs->dc = dc;
  return heap_insert(dc->heap,cs);
}


/**

   Function: int dc_remove(struct dc* dc, struct chunksrv* cs)
   -----------------------------------------------------------

   Remove `cs` from `dc`

**/


int dc_remove(struct dc* dc, struct chunksrv* cs)
{
  cs->dc = NULL;
  return heap_remove(dc->heap,cs);
}


/**

   Function: struct chunksrv* dc_extract(struct dc* dc)
   ----------------------------------------------------

   Extract minimal chunk server from `dc`

**/


struct chunksrv* dc_extract(struct dc* dc)
{
  return heap_extract(dc->heap);
}



/**

   Function: int dc_compare(struct dc* dc01, struct dc* dc02)
   ----------------------------------------------------------

   Compare dc's according to their id

**/


int dc_compare(struct dc* dc01, struct dc* dc02)
{
  if ( (dc01) && (dc02) )
    {
      return (dc01->id - dc02->id);
    }

  return 0;
}
